home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / dialogs / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-02  |  9.0 KB  |  284 lines

  1. /*
  2.  * FILE.C
  3.  *
  4.  * Code demonstrating the various uses of the GetOpenFileName and
  5.  * GetSaveFileName common dialogs.
  6.  *
  7.  * Copyright (c)1992 Microsoft Corporation, All Right Reserved
  8.  *
  9.  * Kraig Brockschmidt, Software Design Engineer
  10.  * Microsoft Systems Developer Relations
  11.  * One Microsoft Way
  12.  * Redmond, WA  98052
  13.  *
  14.  * Internet  :  kraigb@microsoft.com
  15.  * Compuserve:  70750,2344
  16.  * Fax       :  (206)936-7329
  17.  */
  18.  
  19. #include <windows.h>
  20. #include <commdlg.h>
  21. #include <dlgs.h>
  22. #include <memory.h>
  23. #include "dialogs.h"
  24.  
  25.  
  26.  
  27.  
  28. /*
  29.  * ReplaceCharWithNull
  30.  *
  31.  * Purpose:
  32.  *  Walks a null-terminated string and replaces a given character
  33.  *  with a zero.  Used to turn a single string for file open/save
  34.  *  filters into the appropriate filter string as required by the
  35.  *  common dialog API.
  36.  *
  37.  * Parameters:
  38.  *  psz             LPSTR to the string to process.
  39.  *  ch              int character to replace.
  40.  *
  41.  * Return Value:
  42.  *  int             Number of characters replaced.  -1 if psz is NULL.
  43.  */
  44.  
  45. int FAR PASCAL ReplaceCharWithNull(LPSTR psz, int ch)
  46.     {
  47.     int             cChanged=-1;
  48.  
  49.     if (NULL!=psz)
  50.         {
  51.         while (0!=*psz)
  52.             {
  53.             if (ch==*psz)
  54.                 {
  55.                 *psz=0;
  56.                 cChanged++;
  57.                 }
  58.             psz++;
  59.             }
  60.         }
  61.     return cChanged;
  62.     }
  63.  
  64.  
  65.  
  66.  
  67.  
  68. /*
  69.  * FileDialogs
  70.  *
  71.  * Purpose:
  72.  *  Invokes variations on the GetOpenFileName and GetSaveFileName
  73.  *  common dialogs.
  74.  *
  75.  * Parameters:
  76.  *  hWndOwner       HWND to use as the owner of the dialog.
  77.  *  iDialog         WORD indicating which dialog variation to invoke.
  78.  *
  79.  * Return Value:
  80.  *  BOOL            TRUE if the function was successful, FALSE otherwise.
  81.  */
  82.  
  83. BOOL PASCAL FileDialogs(HWND hWndOwner, WORD iDialog)
  84.     {
  85.     OPENFILENAME        ofn;
  86.     BOOL                fRet=FALSE;
  87.     int                 cch;
  88.     char                szDefExt[5];        //Default extension
  89.     char                szFile[256];        //Filename buffer
  90.     char                szFilters[256];     //Standard filters string
  91.     char                szCFilter[256];     //Custom filter string
  92.  
  93.  
  94.     /*
  95.      * Standard initialization is clearing the filename buffer, loading
  96.      * the default extension string, and loading the default filter string.
  97.      * To simplify filter string initialization, we define a single string
  98.      * in the stringtable with embedded '|' characters where there should
  99.      * be zeros.  By placing the character to replace at the end of the
  100.      * string, we can dynamically pass it (szFilters[cch-1] to
  101.      * ReplaceCharWithNull that embeds the zeros for us.
  102.      */
  103.     szFile[0]=0;
  104.     LoadString(hgInst, IDS_DEFEXT,  szDefExt, 5);
  105.  
  106.     LoadString(hgInst, IDS_FILTERS, szFilters, sizeof(szFilters));
  107.     cch=lstrlen(szFilters);
  108.     ReplaceCharWithNull(szFilters, szFilters[cch-1]);
  109.  
  110.  
  111.     /*
  112.      * Standard Initialization for all invocations.  This represents
  113.      * the minimal initialization for a functional GetOpenFileName call,
  114.      * with exception of the Flags that we set in the cases below.
  115.      */
  116.     memset(&ofn, 0, sizeof(OPENFILENAME));
  117.     ofn.lStructSize =sizeof(OPENFILENAME);
  118.     ofn.hwndOwner   =hWndOwner;
  119.     ofn.lpstrFile   =szFile;          //Gotta have somewhere to put a filename
  120.     ofn.nMaxFile    =sizeof(szFile);
  121.     ofn.lpstrDefExt =szDefExt;
  122.     ofn.lpstrFilter =szFilters;
  123.     ofn.nFilterIndex=1;               //Selects the first filter in lpstrFilter
  124.  
  125.  
  126.     switch (iDialog)
  127.         {
  128.         case IDM_FILEFUNCTIONALOPEN:
  129.             //Hide the Read-Only checkbox and insist on returning a real file.
  130.             ofn.Flags=OFN_FILEMUSTEXIST | OFN_SHOWHELP; //OFN_HIDEREADONLY |
  131.             fRet=GetOpenFileName(&ofn);
  132.  
  133.             /*
  134.              * At this point szFile will contain the selected filename
  135.              * including the entire path.  nFilterIndex will contain the
  136.              * last selected filter index.
  137.              */
  138.             break;
  139.  
  140.  
  141.         case IDM_FILEFUNCTIONALSAVEAS:
  142.             /*
  143.              * Only difference between this and Open above is the API call.
  144.              * We also add the OFN_CREATEPROMPT to this call to have the
  145.              * dialog actually create a file if the given name does not exist.
  146.              * OFN_CREATEPROMPT automatically enforces file existence.
  147.              *
  148.              * We also hook this invocation to show processing of the
  149.              * registered messages.
  150.              */
  151.             ofn.lpfnHook=(DLGHOOKPROC)MakeProcInstance(FileHook, hgInst);
  152.             ofn.Flags=OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_ENABLEHOOK;
  153.  
  154.             fRet=GetSaveFileName(&ofn);
  155.  
  156.             FreeProcInstance((FARPROC)ofn.lpfnHook);
  157.             break;
  158.  
  159.  
  160.         case IDM_FILECUSTOMFILTER:
  161.             ofn.Flags=OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
  162.  
  163.             //Load and initialize the single custom filter we'll use.
  164.             LoadString(hgInst, IDS_CUSTOMFILTER, szCFilter, sizeof(szCFilter));
  165.             cch=lstrlen(szCFilter);
  166.             ReplaceCharWithNull(szCFilter, szCFilter[cch-1]);
  167.  
  168.             ofn.lpstrCustomFilter=szCFilter;
  169.             ofn.nMaxCustFilter   =sizeof(szCFilter);
  170.  
  171.             //Must specify zero here to use and enable the custom filter
  172.             ofn.nFilterIndex=0;
  173.  
  174.             fRet=GetOpenFileName(&ofn);
  175.             break;
  176.  
  177.  
  178.         case IDM_FILEEXTRAINITIALVALUES:
  179.             /*
  180.              * A few additional thing you can do:  show the read-only
  181.              * checkbox by excluding OFN_HIDEREADONLY and check it with
  182.              * OFN_READONLY.  Also specify an initial directory and a
  183.              * replacement title bar.
  184.              */
  185.             ofn.Flags     =OFN_FILEMUSTEXIST | OFN_READONLY;
  186.             ofn.lpstrTitle="File Open";
  187.  
  188.             //We're using szCFilter here as a scratch buffer
  189.             GetWindowsDirectory(szCFilter, sizeof(szCFilter));
  190.             ofn.lpstrInitialDir=szCFilter;
  191.  
  192.             fRet=GetOpenFileName(&ofn);
  193.             break;
  194.         }
  195.  
  196.     return fRet;
  197.     }
  198.  
  199.  
  200.  
  201.  
  202. /*
  203.  * FileHook
  204.  *
  205.  * Purpose:
  206.  *  Processes messages from the common File Open dialog to demonstrate
  207.  *  processing of registered SHAREVISTRING and FILEOKSTRING messages.
  208.  *
  209.  * Parameters:
  210.  *  hDlg            HWND of the dialog box.
  211.  *  iMsg            UINT message number.
  212.  *  wParam          UINT parameter.
  213.  *  lParam          LONG parameter.
  214.  *
  215.  * Return Value:
  216.  *  UINT            Non-Zero or Zero, indicating if the common dialog should
  217.  *                  SKIP the message (non-zero) or not (zero).  Don't confuse
  218.  *                  with typical dialog box return values.
  219.  */
  220.  
  221. UINT FAR PASCAL FileHook(HWND hDlg, UINT iMsg, UINT wParam, LONG lParam)
  222.     {
  223.     LPOPENFILENAME  pOFN;
  224.     char            szTemp[128];
  225.     char            szTitle[15];
  226.  
  227.     if (iMSGShareViolation==iMsg)
  228.         {
  229.         /*
  230.          * When the OK button is pressed, the file dialog may attempt
  231.          * to create a file on a protected share, or may attempt to
  232.          * open a locked file.  If the dialog did not have the
  233.          * OFN_SHAREAWARE flag, then the SHAREVISTRING message is sent
  234.          * to the hook.
  235.          *
  236.          * The return value is either OFN_SHAREFALLTHROUGH meaning that
  237.          * the dialog ignores the sharing violation and returns the
  238.          * filename to the caller anyway.  OFN_SHARENOWARN causes the
  239.          * call to fail but nothing else happens.  OFN_SHAREWARN causes
  240.          * the dialog to display a warning message, as if there were no
  241.          * hook.
  242.          */
  243.  
  244.         pOFN=(LPOPENFILENAME)lParam;
  245.  
  246.         //Get the filename without the path with this COMMDLG helper.
  247.         GetFileTitle(pOFN->lpstrFile, szTitle, 15);
  248.         wsprintf(szTemp, "Sharing Violation on %s.  Ignore?", (LPSTR)szTitle);
  249.         wParam=MessageBox(hDlg, szTemp, "GetOpenFileName", MB_YESNO);
  250.  
  251.         if (IDYES==wParam)
  252.             return OFN_SHAREFALLTHROUGH;    //Or OFN_SHARENOWARN.
  253.         else
  254.             return OFN_SHAREWARN;
  255.         }
  256.  
  257.     if (iMSGFileOK==iMsg)
  258.         {
  259.         /*
  260.          * User pressed the OK button and the dialog is ready to close.
  261.          * lParam is a pointer to the OPENFILENAME structure, so here
  262.          * we can validate the filename in lpstrFile or lpstrFileTitle
  263.          * and prevent the dialog from closing by returning TRUE.
  264.          *
  265.          * We do it the cheap way and just ask the user to visually
  266.          * validate.
  267.          */
  268.  
  269.         pOFN=(LPOPENFILENAME)lParam;
  270.  
  271.         //Get the filename without the path with this COMMDLG helper.
  272.         GetFileTitle(pOFN->lpstrFile, szTitle, 15);
  273.         wsprintf(szTemp, "Is %s a valid filename?", (LPSTR)szTitle);
  274.  
  275.         wParam=MessageBox(hDlg, szTemp, "GetOpenFileName", MB_YESNO);
  276.  
  277.         //If the user said the filename is NOT valid, prevent dialog closure.
  278.         if (IDNO==wParam)
  279.             return TRUE;
  280.         }
  281.  
  282.     return FALSE;
  283.     }
  284.